const std = @import("std");
const net = std.net;
const io = std.io;

pub fn main() !void {
    // 创建分配器
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // 解析服务器地址和端口
    const server_address = try net.Address.parseIp("127.0.0.1", 3000);
    std.debug.print("正在连接到服务器 {}...\n", .{server_address});

    // 连接到服务器
    const stream = net.tcpConnectToAddress(server_address) catch |err| {
        // 根据不同错误类型进行处理
        switch (err) {
            error.ConnectionRefused => std.debug.print("连接被拒绝，请检查服务器是否启动\n", .{}),
            error.NetworkUnreachable => std.debug.print("网络不可达\n", .{}),
            else => std.debug.print("连接失败: {}\n", .{err}),
        }
        return; // 处理完错误后退出
    };
    defer stream.close();

    std.debug.print("已成功连接到服务器！\n", .{});

    const writer = stream.writer();
    const reader = stream.reader();
    const stdin = io.getStdIn().reader();

    // 缓冲区用于接收服务器消息
    var buffer: [1024]u8 = undefined;

    // 读取服务器的欢迎消息
    if (try reader.readUntilDelimiterOrEof(&buffer, '\n')) |msg| {
        std.debug.print("服务器: {s}", .{msg});
    }

    // 读取服务器的使用说明
    if (try reader.readUntilDelimiterOrEof(&buffer, '\n')) |msg| {
        std.debug.print("服务器: {s}", .{msg});
    }

    // 与服务器交互
    while (true) {
        // 提示用户输入
        std.debug.print("> ", .{});

        // 读取用户输入
        const input = try stdin.readUntilDelimiterOrEofAlloc(allocator, '\n', 1024);
        //defer allocator.free(input);

        if (input) |line| {
            // 发送输入到服务器
            try writer.print("{s}\n", .{line});

            // 如果输入quit，退出循环
            if (std.mem.eql(u8, line, "quit")) {
                break;
            }

            // 读取服务器响应
            const response = try reader.readUntilDelimiterOrEof(&buffer, '\n');
            if (response) |msg| {
                std.debug.print("服务器: {s}", .{msg});
            } else {
                std.debug.print("与服务器的连接已关闭\n", .{});
                break;
            }
        } else {
            break;
        }
    }

    std.debug.print("客户端已退出\n", .{});
}
